package com.weipai.education.service.impl;

import com.weipai.education.dao.*;
import com.weipai.education.enums.ExchangeStatus;
import com.weipai.education.enums.PurchaseStatus;
import com.weipai.education.enums.RetCode;
import com.weipai.education.enums.UserType;
import com.weipai.education.model.*;
import com.weipai.education.model.api.PageResult;
import com.weipai.education.model.api.Response;
import com.weipai.education.service.ExchangeService;
import com.weipai.education.utils.OrderNumberUtils;
import com.weipai.education.utils.SessionUserUtil;
import org.omg.CORBA.Object;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * @Author: 曹朋飞
 * @Date: 2018/12/17 17:27
 */
@Service
public class ExchangeServiceImpl implements ExchangeService {

    @Autowired
    private ExchangeDao exchangeDao;
    @Autowired
    private SessionUserUtil sessionUserUtil;
    @Autowired
    private PurchaseDao purchaseDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserCategoryDao userCategoryDao;
    @Autowired
    private UserEarningsDao userEarningsDao;
    @Autowired
    private SystemDao systemDao;
    @Autowired
    private ProductCateDao productCateDao;
    @Autowired
    private InventoryDao inventoryDao;
    @Autowired
    private ProductDao productDao;

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public Response save(Exchange exchange, String goodsBarCode, Integer orderId, Integer isHeadset) {
        Response response = new Response();

        //从session中获得userIdf
        String userId = sessionUserUtil.getUser().getId().toString();

        if (isHeadset == 1) { //需要货号
            String[] fields = goodsBarCode.split("\n");
            //根据订单id搜订单信息
            Purchase purchase = purchaseDao.getPurchaseByPurchaseNumber(exchange.getPurchaseNumber());
            if (purchase.getStatus() == 1 || purchase.getStatus() == 2) {     //有货号
                //根据货号和订单号搜索是否存在
                for (String BarCode : fields) {
                    //根据userId和goodsBarCode查询此账户下是否有这个商品

                    Integer purchaseDetail = purchaseDao.selectBarcodeByOrderNumber(BarCode, exchange.getPurchaseNumber());
                    if (null == purchaseDetail || purchaseDetail == 0) {
                        response.setCode(RetCode.NOT_DATA);
                        response.put("goodsBarCode", "未找到[" + BarCode + "]商品");
                        return response;
                    }
                }
            }

            String orderNumber = OrderNumberUtils.outTradeNo();
            exchange.setInitUserId(Integer.parseInt(userId)).setOrderNumber(orderNumber)
                    .setStatus(ExchangeStatus.NO_AUDIT.getType());
//            exchange.setMoney(new BigDecimal(exchange.getMoney()));
            exchangeDao.save(exchange);
            //添加记录
            for (String field : fields) {
                ExchangeDetail exchangeDetail = new ExchangeDetail();
                exchangeDetail.setExchangeOrderNumber(orderNumber).setGoodsBarCode(field);
                exchangeDao.insertExchangeDetail(exchangeDetail);
            }
        } else { //不需要货号
            String orderNumber = OrderNumberUtils.outTradeNo();
            exchange.setInitUserId(Integer.parseInt(userId)).setOrderNumber(orderNumber)
                    .setStatus(ExchangeStatus.NO_AUDIT.getType());
            exchangeDao.save(exchange);

            for (int i = 0; i < exchange.getProductNumber(); i++) {
                ExchangeDetail exchangeDetail = new ExchangeDetail();
                exchangeDetail.setExchangeOrderNumber(orderNumber).setGoodsBarCode("");
                exchangeDao.insertExchangeDetail(exchangeDetail);
            }
        }

        //改变订单表的退换货状态
        Purchase purchase = new Purchase();
        if (exchange.getOrderType() == 1) { //换货
            purchase.setIsExchage(1);
        } else if (exchange.getOrderType() == 2) { //退货
            purchase.setIsReturn(1);
        }
        purchase.setId(orderId);
        purchase.setUpdateTime(new Date());
        purchaseDao.updateByPrimaryKeySelective(purchase);

        //添加消息通知记录
        User user = userDao.selectByPrimaryKey(userId);
        Message message = new Message();
        message.setUserId(user.getId()).setRecommendId(user.getSuperiorId()).setContent("[" + user.getNickname() + "]退货了").setType(3).setSign(0);
        systemDao.insertMsg(message);


        response.setCode(RetCode.SUCCESS);
        return response;
    }

    @Override
    public Response list(Integer page, Integer size, String orderNumber, String orderType,
                         String startTime, String endTime, String type) {

        Response response = new Response();
        String userId = null;
        if (null != type) {
            //从session中获取登录账号信息
            userId = sessionUserUtil.getUser().getId().toString();
        }
        Integer start = (page - 1) * size;
        List<Map<String, Object>> purchases = exchangeDao.list(start, size, startTime, endTime, orderType, userId, orderNumber);
        Integer totalNum = exchangeDao.listAmount(startTime, endTime, orderType, userId, orderNumber);
        PageResult<Map<String, Object>> pageList = new PageResult<>(purchases, page, size, totalNum);
        response.setCode(RetCode.SUCCESS);
        response.put("pageList", pageList);
        return response;
    }

    @Override
    public Response isAudit(String status, String id) {
        Response response = new Response();

        //从session中获取userId
        String userId = sessionUserUtil.getUser().getId().toString();

        Exchange exchange = exchangeDao.selectByPrimaryKey(id);
        if (null != exchange) {
            exchange.setStatus(Integer.parseInt(status));
            exchange.setAuditUserId(Integer.parseInt(userId));
            exchangeDao.updateByPrimaryKeySelective(exchange);

            //给发货人添加库存
            Map<String, java.lang.Object> productInfo = productDao.getProductInfo(Integer.toString(exchange.getProductId()));

            //订单信息
            Purchase purchase = purchaseDao.getPurchaseByPurchaseNumber(exchange.getPurchaseNumber());
            //获取收货人商品的库存情况
            InventoryDetail inventoryDetail = inventoryDao.getInventoryDetail(Integer.toString(purchase.getReceiveUserId()),Integer.toString(purchase.getProductId()),null);
            if(purchase.getStatus() == PurchaseStatus.HAVE_OUTBOUND.getType()){  //出库状态，发货人库存没有记录，发货人出库记录有一条
                // 查找退货记录
                List<Map<String, java.lang.Object>> exchangeDetailList = exchangeDao.getExchangeDetail(exchange.getOrderNumber());
                //发货人加库存
                Inventory inventory = inventoryDao.getInventory(Integer.toString(purchase.getDeliverUserId()), Integer.toString(purchase.getProductId()));
                inventory.setStock(inventory.getStock() + exchange.getProductNumber());
                inventoryDao.updateByPrimaryKeySelective(inventory);
                //发货人的入库记录
                InventoryIn in = new InventoryIn();
                String inOrderNumber = OrderNumberUtils.outTradeNo();
                in.setPurchaseNumber(purchase.getPurchaseNumber()).setInOrderNumber(inOrderNumber)
                        .setDeliverUserId(purchase.getDeliverUserId()).setProductId(purchase.getProductId())
                        .setProductNumber(exchange.getProductNumber()).setReceiveUserId(purchase.getReceiveUserId()).setStatus(0);
                inventoryDao.saveInventoryIn(in);
                if((int)productInfo.get("isHeadset") == 1){ //有货号
                    for (Map<String, java.lang.Object> exchangeInfo :exchangeDetailList ) {
                        InventoryDetail inventoryDetail1 = new InventoryDetail();
                        InventoryInDetail inventoryInDetail = new InventoryInDetail();
                        inventoryInDetail.setInOrderNumber(inOrderNumber).setIsDamage(inventoryDetail.getIsDamage()).setIsPrice(inventoryDetail.getIsPrice());

                            //入库记录明细
                            inventoryInDetail.setGoodsBarCode((String)exchangeInfo.get("goods_bar_code"));
                            inventoryDao.saveInventoryInDetail(inventoryInDetail);

                            //库存明细
                            inventoryDetail1.setGoodsBarCode((String)exchangeInfo.get("goods_bar_code")).setProductId(purchase.getProductId()).setUserId(purchase.getDeliverUserId()).setIsDamage(inventoryDetail.getIsDamage()).setIsPrice(inventoryDetail.getIsPrice());
                            inventoryDao.saveInventoryDetail(inventoryDetail1);
                    }
                }else{ //没有货号，随便加几条记录
                    for (Integer i =0;i<exchange.getProductNumber();i++) {
                        InventoryDetail inventoryDetail1 = new InventoryDetail();
                        InventoryInDetail inventoryInDetail = new InventoryInDetail();
                        inventoryInDetail.setInOrderNumber(inOrderNumber).setIsDamage(inventoryDetail.getIsDamage()).setIsPrice(inventoryDetail.getIsPrice());

                        //入库记录明细
                        inventoryInDetail.setGoodsBarCode("");
                        inventoryDao.saveInventoryInDetail(inventoryInDetail);

                        //库存明细
                        inventoryDetail1.setGoodsBarCode("").setProductId(purchase.getProductId()).setUserId(purchase.getReceiveUserId()).setIsDamage(inventoryDetail.getIsDamage()).setIsPrice(inventoryDetail.getIsPrice());
                        inventoryDao.saveInventoryDetail(inventoryDetail1);
                    }
                }
            }else if(purchase.getStatus() == PurchaseStatus.HAVE_INBOUND.getType()){ //入库记录，入库记录有一条，收货人库存有
                // 退货详情
                List<Map<String, java.lang.Object>> exchangeDetailList = inventoryDao.getAllInventoryOutDetail(purchase.getPurchaseNumber(),purchase.getReceiveUserId(),purchase.getProductId());
                List<Integer> inventoryDetailId = new ArrayList<>();
                if(exchangeDetailList == null){
                    response.setCode(RetCode.NOT_FIND_ORDERNUMBER);
                    return response;
                }
                //发货人加库存
                Inventory inventory = inventoryDao.getInventory(Integer.toString(purchase.getDeliverUserId()), Integer.toString(purchase.getProductId()));
                inventory.setStock(inventory.getStock() + exchange.getProductNumber());
                inventoryDao.updateByPrimaryKeySelective(inventory);
                //发货人添加入库记录
                //入库记录
                InventoryIn in = new InventoryIn();
                String inOrderNumber = OrderNumberUtils.outTradeNo();
                in.setPurchaseNumber(purchase.getPurchaseNumber()).setInOrderNumber(inOrderNumber)
                        .setDeliverUserId(purchase.getDeliverUserId()).setProductId(purchase.getProductId())
                        .setProductNumber(exchange.getProductNumber()).setReceiveUserId(purchase.getReceiveUserId()).setStatus(0);
                inventoryDao.saveInventoryIn(in);
//库存明细
                InventoryDetail inventoryDetail1 = new InventoryDetail();
                InventoryInDetail inventoryInDetail = new InventoryInDetail();
                inventoryInDetail.setInOrderNumber(inOrderNumber).setIsDamage(inventoryDetail.getIsDamage()).setIsPrice(inventoryDetail.getIsPrice());
                if((int)productInfo.get("isHeadset") == 1){ //有货号
                    for (Map<String, java.lang.Object> tempExchange:exchangeDetailList) {
                        if(tempExchange.get("goods_bar_code") != null){
                            //入库记录明细
                            inventoryInDetail.setGoodsBarCode((String)tempExchange.get("goods_bar_code"));
                            inventoryDao.saveInventoryInDetail(inventoryInDetail);

                            //库存明细
                            inventoryDetail1.setGoodsBarCode((String)tempExchange.get("goods_bar_code")).setProductId(purchase.getProductId()).setUserId(purchase.getDeliverUserId()).setIsDamage(inventoryDetail.getIsDamage()).setIsPrice(inventoryDetail.getIsPrice());
                            inventoryDao.saveInventoryDetail(inventoryDetail1);
                        }
                        inventoryDetailId.add((Integer)tempExchange.get("inventoryDetailId"));
                    }
                    //减库存

                    Inventory inventory22 = inventoryDao.getInventory(Integer.toString(purchase.getReceiveUserId()), Integer.toString(purchase.getProductId()));
                    inventory22.setStock(inventory22.getStock() - exchange.getProductNumber());
                    inventoryDao.updateByPrimaryKeySelective(inventory22);

                    //收货人减库存
                    inventoryDao.batchDeleteInventoryDetailById(inventoryDetailId);
                    //出库记录
                    InventoryOut out = new InventoryOut();
                    String outOrderNumber = OrderNumberUtils.outTradeNo();
                    out.setPurchaseNumber(purchase.getPurchaseNumber()).setOutOrderNumber(outOrderNumber)
                            .setDeliverUserId(purchase.getReceiveUserId()).setProductId(purchase.getProductId())
                            .setProductNumber(exchange.getProductNumber()).setReceiveUserId(purchase.getReceiveUserId()).setStatus(0);
                    inventoryDao.saveInventoryOut(out);

                    //出库记录明细
                    for (Map<String, java.lang.Object> tempExchange:exchangeDetailList) {
                        if(tempExchange.get("goods_bar_code") != null) {
                            InventoryOutDetail inventoryOutDetail = new InventoryOutDetail();
                            inventoryOutDetail.setOutOrderNumber(outOrderNumber).setGoodsBarCode((String) tempExchange.get("goods_bar_code")).setIsDamage(inventoryDetail.getIsDamage()).setIsPrice(inventoryDetail.getIsPrice());
                            inventoryDao.saveInventoryOutDetail(inventoryOutDetail);
                        }
                    }
                }else{

                    List<Map<String, Integer>> product = inventoryDao.selectDetailPeoduct(purchase.getProductId(), purchase.getReceiveUserId(), exchange.getProductNumber());

                    if (!product.isEmpty()) {
                        for (Map<String, Integer> map : product) {
                            inventoryDetailId.add(map.get("id"));

                            inventoryInDetail.setGoodsBarCode("");
                            inventoryDao.saveInventoryInDetail(inventoryInDetail);

                            inventoryDetail1.setGoodsBarCode("").setProductId(purchase.getProductId()).setUserId(purchase.getDeliverUserId()).setIsDamage(inventoryDetail.getIsDamage()).setIsPrice(inventoryDetail.getIsPrice());
                            inventoryDao.saveInventoryDetail(inventoryDetail1);
                        }
                    }
                    //减库存
                    inventory.setStock(inventory.getStock() - exchange.getProductNumber());
                    inventoryDao.updateByPrimaryKeySelective(inventory);

                    //收货人减库存
                    inventoryDao.batchDeleteInventoryDetailById(inventoryDetailId);
                    //出库记录
                    InventoryOut out = new InventoryOut();
                    String outOrderNumber = OrderNumberUtils.outTradeNo();
                    out.setPurchaseNumber(purchase.getPurchaseNumber()).setOutOrderNumber(outOrderNumber)
                            .setDeliverUserId(purchase.getReceiveUserId()).setProductId(purchase.getProductId())
                            .setProductNumber(exchange.getProductNumber()).setReceiveUserId(purchase.getReceiveUserId()).setStatus(0);
                    inventoryDao.saveInventoryOut(out);

                    //出库记录明细
                    for (int i = 0; i < exchange.getProductNumber(); i++) {
                        InventoryOutDetail inventoryOutDetail = new InventoryOutDetail();
                        inventoryOutDetail.setOutOrderNumber(outOrderNumber).setGoodsBarCode("").setIsDamage(inventoryDetail.getIsDamage()).setIsPrice(inventoryDetail.getIsPrice());
                        inventoryDao.saveInventoryOutDetail(inventoryOutDetail);
                    }
                }
            }

            if (Integer.parseInt(status) == 1 && exchange.getOrderType() == 2) { //通过 OrderType  1换货 2退货
                //退钱
                //根据商品id获取商品分类是否是耳机
                ProductCate productCate = productCateDao.selectByProductId(exchange.getProductId());
                if(productCate.getIsHeadset() == 1){ //表示是有货号的
//发起退货人的信息
                    User user = userDao.selectByPrimaryKey(Integer.toString(exchange.getInitUserId()));
                    //发起退货人的推荐人的信息
                    User referrerUser = userDao.selectByPrimaryKey(Integer.toString(user.getReferrerId()));

                    if (null != referrerUser) {
                        //发起退货人的推荐人的类别
                        UserCategory referrerUserCate = userCategoryDao.selectByPrimaryKey(Integer.toString(referrerUser.getUserCateId()));

                        BigDecimal goodsReward = referrerUserCate.getGoodsReward();
                        referrerUser.setGoodsReward(referrerUser.getGoodsReward().add(goodsReward));
                        userDao.updateByPrimaryKeySelective(referrerUser);

                        addMessage(user,goodsReward,referrerUser.getId());
                        //奖金记录
                        saveUserEarnings(referrerUser.getId(), goodsReward, 3, exchange.getInitUserId(), exchange.getPurchaseNumber());
                    }

                    for (Integer i = 2; i <= 3; i++) {
                        //查询我所在区域上面的代理
                        User userSuperior = userDao.getCityCountyUser(user.getProvince(), user.getCity(), user.getCounty(), i);
                        if (userSuperior.getType() == UserType.SELL_USER.getType()) {
//我的推荐人类别
                            UserCategory referrerUserCate = userCategoryDao.selectByPrimaryKey(Integer.toString(userSuperior.getUserCateId()));

                            //我上级的提成比例
                            BigDecimal areaGoodsReward = referrerUserCate.getAreaGoodsReward();

                            //计算上级应得的推荐奖
                            userSuperior.setGoodsReward(userSuperior.getGoodsReward().add(areaGoodsReward));

                            userDao.updateByPrimaryKeySelective(userSuperior);
                            addMessage(user,areaGoodsReward,userSuperior.getId());
                            //奖金记录
                            saveUserEarnings(userSuperior.getId(), areaGoodsReward, 3, user.getId(), exchange.getPurchaseNumber());
                        }
                    }
                }
            }

            response.setCode(RetCode.SUCCESS);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    /**
     * 奖金记录
     *
     * @param userId：得奖人id
     * @param rewardPrice：奖金
     * @param type：1推荐奖，2拿货奖
     * @param offerUserId：新人
     */
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public void saveUserEarnings(Integer userId, BigDecimal rewardPrice, Integer type, Integer offerUserId, String purchaseNumber) {
        UserEarnings earnings = new UserEarnings();
        earnings.setUserId(userId).setRewardPrice(rewardPrice).setType(type)
                .setOfferUserId(offerUserId).setPurchaseNumber(purchaseNumber);
        userEarningsDao.insert(earnings);
    }
    @Override
    /**
     * user 被推荐人的信息
     * price 分成的钱
     * userId 推荐人的id
     */
    public void addMessage(User user,BigDecimal price,Integer userId ){
        //添加消息通知记录
        Message message = new Message();
        message.setUserId(user.getId()).setRecommendId(userId).setContent("您推荐的[" + user.getNickname() + "]退货，扣除奖励"+ price+"元，可前往【我的收益】查看").setType(2).setSign(0);
        systemDao.insertMsg(message);
    }
    @Override
    public Response exchangeInfo(String id) {
        Response response = new Response();
        List<Map<String, Object>> list = exchangeDao.exchangeInfo(id);
        if (!list.isEmpty()) {
            response.setCode(RetCode.SUCCESS);
            response.setData(list);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }
}
